Pixbuf properties
authorMatthias Clasen <matthiasc@src.gnome.org>
Thu, 5 Jul 2007 19:50:03 +0000 (19:50 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Thu, 5 Jul 2007 19:50:03 +0000 (19:50 +0000)
svn path=/trunk/; revision=18383

ChangeLog
docs/reference/ChangeLog
docs/reference/gtk/tmpl/gtkbuilder.sgml
gtk/gtkbuilder.c

index 4eb7f5cf2357b384c9005d6f6c293e1bf7ec204c..b4d24ed3f28081e0d36bb7eedb074bf645469cf5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-07-05  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkbuilder.c: Support pixbuf properties by specifying
+       a filename as the property value.  (#447966)
+
 Wed Jul  4 12:20:23 2007  Tim Janik  <timj@imendio.com>
 
        * gdk/gdkevents.c (gdk_event_request_motions): added usage example
index 5fccb2e4b424c64746fdd7ec504c9b3e48f0e7f8..a1b27a2a126e1bea2e8e577a9cc9d07f2012b6f7 100644 (file)
@@ -1,3 +1,7 @@
+2007-04-05  Matthias clasen  <mclasen@redhat.com>
+
+       * gtk/tmpl/gtkbuilder.sgml: Pixbuf properties
+
 2007-07-04  Johan Dahlin  <jdahlin@async.com.br>
 
        * gtk/gtk-builder-convert.xml: We support GtkComboBox.items 
index 705bb7bab44ec36e2c05a161cf15aeb3ed66deab..f9a45d74d13bb2829098ee81722cf9528c4cd28e 100644 (file)
@@ -126,6 +126,7 @@ name, nick or integer value), flags (can be specified by their name,
 nick, integer value, optionally combined with "|", e.g. 
 "GTK_VISIBLE|GTK_REALIZED")  and colors (in a format understood by 
 gdk_color_parse()). Objects can be referred to by their name. 
+Pixbufs can be specified as a filename of an image file to load.
 In general, GtkBuilder allows forward references to objects &mdash; 
 an object doesn't have to constructed before it can be referred to.
 The exception to this rule is that an object has to be constructed
index 6f758cad216132ae58a9b3781ae162c20c372df0..81e0c0f7dd859e6f3052be29ab34c8596ee18a73 100644 (file)
@@ -34,6 +34,8 @@
 #include "gtkprivate.h"
 #include "gtktypebuiltins.h"
 #include "gtkwindow.h"
+#include "gtkicontheme.h"
+#include "gtkstock.h"
 #include "gtkalias.h"
 
 static void gtk_builder_class_init     (GtkBuilderClass *klass);
@@ -68,6 +70,7 @@ struct _GtkBuilderPrivate
   GSList *signals;
   gchar *current_root;
   GSList *root_objects;
+  const gchar *filename;
 };
 
 G_DEFINE_TYPE (GtkBuilder, gtk_builder, G_TYPE_OBJECT)
@@ -286,7 +289,8 @@ gtk_builder_get_parameters (GtkBuilder  *builder,
 
       parameter.name = prop->name;
 
-      if (G_IS_PARAM_SPEC_OBJECT (pspec))
+      if (G_IS_PARAM_SPEC_OBJECT (pspec) &&
+          (G_PARAM_SPEC_VALUE_TYPE (pspec) != GDK_TYPE_PIXBUF))
         {
           if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
             {
@@ -647,6 +651,8 @@ gtk_builder_add_from_file (GtkBuilder   *builder,
       return 0;
     }
   
+  builder->priv->filename = filename;
+
   _gtk_builder_parser_parse_buffer (builder, filename,
                                     buffer, length,
                                     &tmp_error);
@@ -689,6 +695,8 @@ gtk_builder_add_from_string (GtkBuilder   *builder,
 
   tmp_error = NULL;
 
+  builder->priv->filename = ".";
+
   _gtk_builder_parser_parse_buffer (builder, "<input>",
                                     buffer, length,
                                     &tmp_error);
@@ -1170,34 +1178,65 @@ gtk_builder_value_from_string_type (GtkBuilder   *builder,
         ret = FALSE;
       break;
     case G_TYPE_OBJECT:
-#if 0
-        if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF))
-      {
-        gchar *filename;
-        GError *tmp_error = NULL;
-        GdkPixbuf *pixbuf;
+      if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF))
+        {
+          gchar *filename;
+          GError *tmp_error = NULL;
+          GdkPixbuf *pixbuf;
+       
+          if (gtk_builder_get_object (builder, string))
+            {
+              g_set_error (error,
+                           GTK_BUILDER_ERROR,
+                           GTK_BUILDER_ERROR_INVALID_VALUE,
+                           "Could not load image '%s': "
+                           " '%s' is already used as object id",
+                           string, string);
+              return FALSE;
+            }
 
-        filename = gtk_xml_relative_file (xml, string);
-        pixbuf = gdk_pixbuf_new_from_file (filename, &tmp_error);
-        if (pixbuf)
-          {
-            g_value_set_object (value, pixbuf);
-            g_object_unref (G_OBJECT (pixbuf));
-          }
-        else
-          {
-           g_set_error (error,
-                        GTK_BUILDER_ERROR,
-                        GTK_BUILDER_ERROR_INVALID_VALUE,
-                        "could not load image `%s'",
-                        tmp_error->message);
-            g_error_free (tmp_error);
-            ret = FALSE;
-          }
-        g_free (filename);
-      }
-        else
-#endif
+          if (g_path_is_absolute (string))
+            filename = g_strdup (string);
+          else
+            {
+              gchar *dirname;
+
+              dirname = g_path_get_dirname (builder->priv->filename);
+              filename = g_build_filename (dirname, string, NULL);
+
+              g_free (dirname);
+            }
+
+          pixbuf = gdk_pixbuf_new_from_file (filename, &tmp_error);
+
+          if (pixbuf == NULL)
+            {
+              GtkIconTheme *theme;
+
+              g_warning ("Could not load image '%s': %s", 
+                         string, tmp_error->message);
+              g_error_free (tmp_error);
+
+              /* fall back to a missing image */
+              theme = gtk_icon_theme_get_default ();
+              pixbuf = gtk_icon_theme_load_icon (theme, 
+                                                 GTK_STOCK_MISSING_IMAGE,
+                                                 16,
+                                                 GTK_ICON_LOOKUP_USE_BUILTIN,
+                                                 NULL);
+            }
+          if (pixbuf)
+            {
+              g_value_set_object (value, pixbuf);
+              g_object_unref (G_OBJECT (pixbuf));
+            }
+
+          g_free (filename);
+
+          ret = TRUE;
+        }
+      else
         ret = FALSE;
       break;
     default: